﻿<!--
  ActionBar 操作按钮栏组件
  
  功能说明：
  - 支持动态配置操作按钮，可设置按钮类型、禁用状态、显示条件等
  - 自动处理按钮数量限制，超出 maxInline 数量的按钮自动放入下拉菜单
  - 支持按钮排序（order 属性）和动态显示/隐藏（show 属性）
  - 支持危险操作样式（danger 属性）
  - 支持自定义点击处理函数和组件事件回调
  
  使用示例：
  <ActionBar 
    :row="rowData" 
    :actions="actionConfigs" 
    :max-inline="3"
    @action="handleAction"
  />
  
  操作配置格式：
  {
    key: 'edit',           // 操作唯一标识
    label: '编辑',         // 按钮文字
    type: 'primary',       // 按钮类型
    text: true,           // 是否为文字按钮
    link: false,          // 是否为链接按钮
    disabled: false,      // 是否禁用（支持函数）
    show: true,           // 是否显示（支持函数）
    order: 1,             // 排序权重
    danger: false,        // 是否为危险操作
    divided: false,       // 下拉菜单项是否显示分割线
    onClick: (row) => {}  // 自定义点击处理函数
  }
-->
<template>
  <!-- 操作按钮栏容器 -->
  <div class="q-action-bar">
    <!-- 行内按钮区域：显示前 maxInline 个操作按钮 -->
    <template v-for="(act, i) in inlineActions" :key="act.key || i">
      <el-button
        :type="act.type || 'primary'"
        :text="act.text !== false"
        :link="!!act.link"
        :disabled="isDisabled(act)"
        @click="handleClick(act)"
      >
        {{ act.label }}
      </el-button>
      <!-- 按钮分隔符：在按钮之间显示竖线分隔符 -->
      <span v-if="i < inlineActions.length - 1" class="q-action-split">|</span>
    </template>

    <!-- 更多操作下拉菜单：当操作项超过 maxInline 时显示 -->
    <template v-if="dropdownActions.length">
      <!-- 行内按钮和下拉菜单之间的分隔符 -->
      <span v-if="inlineActions.length" class="q-action-split">|</span>
      <el-dropdown
        ref="ddRef"
        trigger="click"
        :placement="placement"
        :popper-class="popperClass"
        :hide-on-click="true"
        @command="handleDropdown"
        @visible-change="onDropdownVisibleChange"
      >
        <!-- 下拉菜单触发器 -->
        <span class="q-more-trigger">
          {{ moreText }}
          <!-- 箭头图标：根据下拉菜单展开状态控制旋转动画 -->
          <i class="iconfont-general gen-shangjiantou1 group-arrow" :class="{ open: isOpen }"></i>
        </span>

        <!-- 下拉菜单内容 -->
        <template #dropdown>
          <el-dropdown-menu>
            <el-dropdown-item
              v-for="(act, i) in dropdownActions"
              :key="act.key || i"
              :disabled="isDisabled(act)"
              :divided="!!act.divided"
              :command="act"
            >
              <!-- 下拉菜单项：支持危险操作样式 -->
              <span :class="['q-dd-item', { 'is-danger': act.danger }]">
                {{ act.label }}
              </span>
            </el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown>
    </template>
  </div>
</template>

<script setup>
  import { ref, computed, watch } from "vue";

  /**
   * 组件属性定义
   * @param {Object} row - 当前行数据，用于操作按钮的上下文判断
   * @param {Array|Function} actions - 操作按钮配置数组或返回配置的函数
   * @param {Number} maxInline - 行内显示的最大按钮数量，超出部分放入下拉菜单
   * @param {String} moreText - 下拉菜单触发按钮的文本
   * @param {String} placement - 下拉菜单的弹出位置
   * @param {String} popperClass - 下拉菜单的自定义样式类名
   */
  const props = defineProps({
    row: { type: Object, required: true },
    actions: { type: [Array, Function], default: () => [] },
    maxInline: { type: Number, default: 3 },
    moreText: { type: String, default: "更多" },
    placement: { type: String, default: "bottom-start" },
    popperClass: { type: String, default: "q-action-dd" },
  });

  /**
   * 组件事件定义
   * @param {String} action - 操作按钮点击事件，参数为操作key和行数据
   */
  const emits = defineEmits(["action"]);

  /* ============================== 响应式状态 ============================== */

  /** 下拉菜单展开状态 */
  const isOpen = ref(false);
  /** 下拉菜单组件引用 */
  const ddRef = ref(null);

  /* ============================== 计算属性 ============================== */

  /**
   * 所有操作按钮配置
   * 支持函数形式动态生成配置，按order排序，过滤隐藏项
   */
  const allActions = computed(() => {
    const list = typeof props.actions === "function" ? props.actions(props.row) : props.actions || [];
    return (list || [])
      .slice()
      .sort((a, b) => (a.order ?? 0) - (b.order ?? 0))
      .filter(a => a.show !== false);
  });

  /** 行内显示的按钮（前 maxInline 个） */
  const inlineActions = computed(() => allActions.value.slice(0, props.maxInline));

  /** 下拉菜单中的按钮（超出 maxInline 的部分） */
  const dropdownActions = computed(() => allActions.value.slice(props.maxInline));

  /* ============================== 事件处理 ============================== */

  /**
   * 下拉菜单显示状态变化处理
   * @param {Boolean} v - 是否显示
   */
  function onDropdownVisibleChange(v) {
    isOpen.value = !!v;
  }

  /**
   * 监听下拉菜单项数量变化
   * 当没有下拉项时，强制收起状态
   */
  watch(
    () => dropdownActions.value.length,
    len => {
      if (!len) isOpen.value = false;
    }
  );

  /**
   * 判断操作按钮是否禁用
   * @param {Object} act - 操作按钮配置
   * @returns {Boolean} 是否禁用
   */
  function isDisabled(act) {
    return typeof act.disabled === "function" ? !!act.disabled(props.row) : !!act.disabled;
  }

  /**
   * 统一的操作按钮处理函数
   * @param {Object} act - 操作按钮配置
   */
  async function handleAction(act) {
    if (!act || isDisabled(act)) return;

    // 执行自定义点击处理函数
    if (typeof act.onClick === "function") {
      await act.onClick(props.row);
    }

    // 触发组件事件
    emits("action", act.key, props.row);
  }

  /**
   * 行内按钮点击处理
   * @param {Object} act - 操作按钮配置
   */
  function handleClick(act) {
    handleAction(act);
  }

  /**
   * 下拉菜单项点击处理
   * @param {Object} act - 操作按钮配置
   */
  function handleDropdown(act) {
    handleAction(act);
  }
</script>

<style scoped>
  /* ============================== 主容器样式 ============================== */

  /** 操作按钮栏主容器：使用弹性布局水平排列 */
  .q-action-bar {
    display: inline-flex;
    align-items: center;
  }

  /* ============================== 分隔符样式 ============================== */

  /** 按钮之间的分隔符：竖线样式 */
  .q-action-split {
    color: var(--cb1);
    margin: 0 2px;
  }

  /* ============================== 下拉菜单触发器样式 ============================== */

  /** 更多操作下拉菜单触发器 */
  .q-more-trigger {
    margin-left: 12px;
    font-weight: 500 !important;
    cursor: pointer;
    color: var(--el-color-primary);
    display: inline-flex;
    align-items: center;
    gap: 4px;
  }

  /* ============================== 下拉菜单项样式 ============================== */

  /** 危险操作的下拉菜单项：红色文字 */
  .q-dd-item.is-danger {
    color: var(--el-color-danger);
  }

  /* ============================== 箭头动画样式 ============================== */

  /** 下拉箭头图标：默认朝下（旋转 180deg），展开时转回 0deg */
  .group-arrow {
    font-size: 14px;
    color: var(--ct4);
    transition: transform 0.2s ease;
    transform: rotate(180deg);
  }

  /** 展开状态的箭头：旋转回 0deg */
  .group-arrow.open {
    transform: rotate(0deg);
  }
</style>
